package com.example.Cairodio;

import java.io.IOException;
import java.util.Vector;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;

/**
 * 
 * @author Monica
 * 
 *         An activity for the playing of the audio clips with a list view for
 *         the avaliable audios and a simple media controller to control the
 *         playing of audio
 */
public class AudioClipsActivity extends Activity implements OnTouchListener,
		OnCompletionListener, OnBufferingUpdateListener {

	public String placeName = "";
	public int placeId;
	static Context context;

	private final String TAG = "AudioPlayer";
	private static int currentPosition = -1;
	private MediaPlayer mediaPlayer;

	private ImageButton PlayPause;
	private ImageButton Previous;
	private ImageButton Next;
	private SeekBar seekBarProgress;
	private ImageButton map;
	private ImageButton Postcard;
	private ImageButton comment;

	private int mediaFileLengthInMilliseconds;
	private final Handler handler = new Handler();
	public Vector<String> urls = new Vector<String>();

	static final int _AudioClipsActivityIntent = 0;
	static final int _CommentsActivityIntent = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.clips_list);

		context = getApplicationContext();

		initView();

		initMediaPlayer();

		initSeekBar();

		Linking();

	}

	/**
	 * @author Monica Farah (eng.monica.farah@gmail.com) the method intialize
	 *         the view by setting the buttons, text views, list view...
	 * 
	 */
	private void initView() {

		// Adapter for the the interaction with the DB

		CairodioDbAdapter dbHelper = ((CairodioApplication) getApplication())
				.getAdapter();

		Bundle b = getIntent().getExtras();
		placeId = b.getInt("placeId");
		placeName = b.getString("placeName");

		urls = dbHelper.getAudioClips(placeId);

		// List view for the audio clips

		ListView Listview = (ListView) findViewById(R.id.AllClipsView);
		ListAdapter myAdapter = new ListAdapter(this, urls.size());
		Listview.setAdapter(myAdapter);

		// Place name as the title
		TextView place = (TextView) findViewById(R.id.place);
		place.setText(placeName);

		// Media Controller buttons (play/pause/previous/next)

		PlayPause = (ImageButton) findViewById(R.id.play);
		Previous = (ImageButton) findViewById(R.id.previous);
		Next = (ImageButton) findViewById(R.id.next);

		// Progress bar
		seekBarProgress = (SeekBar) findViewById(R.id.seekBar);

		// Displaying warning if no clips are
		if (urls.size() == 0) {
			TextView warning = (TextView) findViewById(R.id.warning);
			warning.setVisibility(0);
			warning.setText(R.string.audioclips_activity_warning);
			PlayPause.setVisibility(View.INVISIBLE);
			Previous.setVisibility(View.INVISIBLE);
			Next.setVisibility(View.INVISIBLE);
			seekBarProgress.setVisibility(View.INVISIBLE);

		}

		// buttons for the linking between other views
		map = (ImageButton) findViewById(R.id.map);
		Postcard = (ImageButton) findViewById(R.id.postcard);
		comment = (ImageButton) findViewById(R.id.comments);

		mediaPlayer = new MediaPlayer();

		// if a clip is clicked the clip is played
		Listview.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				currentPosition = position;

				playClip(currentPosition);

			}
		});
	}

	/**
	 * @author Monica Farah (eng.monica.farah@gmail.com) Method for the
	 *         initialization of the media player and setting
	 * 
	 */
	private void initMediaPlayer() {
		if (urls.size() != 0) {

			mediaPlayer.setOnBufferingUpdateListener(this);
			mediaPlayer.setOnCompletionListener(this);

			PlayPause.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {

					if (currentPosition == -1) {
						currentPosition = 0;
						playClip(0);
					} else if (mediaPlayer.isPlaying()) {
						mediaPlayer.pause();
						PlayPause
								.setImageResource(android.R.drawable.ic_media_play);
					} else {
						PlayPause
								.setImageResource(android.R.drawable.ic_media_pause);
						mediaPlayer.start();
					}

					primarySeekBarProgressUpdater();
				}
			});

			Previous.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					currentPosition--;
					if (currentPosition < 0) {
						currentPosition = 0;
						playClip(0);
					} else
						playClip(currentPosition);

				}
			});

			Next.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					currentPosition++;
					if (currentPosition >= urls.size()) {
						currentPosition = 0;
						playClip(0);
					} else
						playClip(currentPosition);

				}
			});
		}
	}

	private void initSeekBar() {

		if (urls.size() != 0) {
			seekBarProgress.setMax(99); // It means 100% .0-99
			seekBarProgress.setOnTouchListener(this);

			seekBarProgress.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					primarySeekBarProgressUpdater();
				}
			});
		}

	}

	/**
	 * @author Monica Farah (eng.monica.farah@gmail.com)
	 * 
	 *         Linking the the view with other views using buttons
	 */
	private void Linking() {
		map.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent returnIntent = new Intent();
				setResult(RESULT_OK, returnIntent);
				finish();

				// if (mediaPlayer.isPlaying())
				mediaPlayer.stop();

			}
		});

		Postcard.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (mediaPlayer.isPlaying())
					mediaPlayer.stop();
				Intent intent = new Intent().setClass(AudioClipsActivity.this,
						TouristicPostCard.class);
				Bundle b = new Bundle();
				b.putString("placeName", placeName);
				intent.putExtras(b);
				startActivity(intent);
			}
		});

		comment.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {

				if (mediaPlayer.isPlaying())
					mediaPlayer.stop();

				Intent intentCommentsActivity = new Intent(
						AudioClipsActivity.this, CommentsActivity.class);
				Bundle b = new Bundle();
				b.putString("placeName", placeName);
				b.putInt("placeID", placeId);
				intentCommentsActivity.putExtras(b);
				startActivityForResult(intentCommentsActivity,
						_CommentsActivityIntent);

			}
		});

	}

	private void primarySeekBarProgressUpdater() {

		seekBarProgress.setProgress((int) (((float) mediaPlayer
				.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100));
		if (mediaPlayer.isPlaying()) {
			Runnable notification = new Runnable() {
				public void run() {
					primarySeekBarProgressUpdater();
				}

			};

			handler.postDelayed(notification, 1000);

		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {

		if (v.getId() == R.id.seekBar) {

			/**
			 * Seekbar onTouch event handler. Method which seeks MediaPlayer to
			 * seekBar primary progress position
			 */

			// if(mediaPlayer.isPlaying()){
			SeekBar sb = (SeekBar) v;
			int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100)
					* sb.getProgress();
			mediaPlayer.seekTo(playPositionInMillisecconds);
			// }
		}
		return false;

	}

	@Override
	public void onCompletion(MediaPlayer mp) {

		if (++currentPosition >= urls.size()) {
			currentPosition = -1;
			primarySeekBarProgressUpdater();
			PlayPause.setImageResource(android.R.drawable.ic_media_play);
		} else

			playClip(currentPosition);

		primarySeekBarProgressUpdater();

	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {

		/**
		 * Method which updates the SeekBar secondary progress by current song
		 * loading from URL position
		 */
		seekBarProgress.setSecondaryProgress(percent);

	}

	/**
	 * @author Monica Farah (eng.monica.farah@gmail.com)
	 * 
	 * @param pos
	 * 
	 *            setting the media player to start playing the audio clip
	 *            according to the selected audio from the list
	 */
	public void playClip(int pos) {

		try {
			mediaPlayer.reset();
			mediaPlayer.setDataSource(urls.get(pos));
			mediaPlayer.prepare();
			mediaPlayer.start();
			mediaFileLengthInMilliseconds = mediaPlayer.getDuration();
			primarySeekBarProgressUpdater();
		} catch (IOException e) {
			Log.e(TAG, "Could not open file for playback.", e);
		}
		PlayPause.setImageResource(android.R.drawable.ic_media_pause);

	}

	public void onDestroy() {

		mediaPlayer.reset();
		mediaPlayer.release();
		stopService(CairodioMapActivity.intent);
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		currentPosition = -1;
		mediaFileLengthInMilliseconds = 0;
		mediaPlayer.stop();
		mediaPlayer.reset();
		primarySeekBarProgressUpdater();
		PlayPause.setImageResource(android.R.drawable.ic_media_play);
		startService(CairodioMapActivity.intent);
		super.onPause();

	}

	public void onStart() {
		super.onStart();
		stopService(CairodioMapActivity.intent);
	}

	@Override
	public void onStop() {
		super.onStop();
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		switch (requestCode) {
		case _CommentsActivityIntent:
			if (resultCode == RESULT_OK) {
				if (mediaPlayer.isPlaying())
					mediaPlayer.stop();
				Intent returnIntent = new Intent();
				setResult(RESULT_OK, returnIntent);
				finish();

				break;
			}

		}

	}

}